﻿using System;
using System.Dynamic;

namespace CSharpTest.Demo3
{
    public class User: Person
    {
        /// <summary>
        /// 常量 类似c++的宏,只在编译的时候使用. 个人不建议使用. 因为各个程序集都使用了同一个常量需要将所有程序集编译
        /// 建议使用static readonly
        /// </summary>
        public const string C = "我是你爸爸";

        public string Name;
        /// <summary>
        /// 自动属性,编译器会自动添加一个私有变量
        /// 属性初始化器
        /// </summary>
        public decimal Money { get; private set; } = 100M;

        /// <summary>
        /// 只读和计算属性
        /// </summary>
        public decimal TotalMoney => Age * 10000;

        /// <summary>
        /// 表达式属性
        /// </summary>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public decimal Make
        {
            set
            {
                if (value <= 0) throw new ArgumentOutOfRangeException(nameof(value));
                Money = Money - 100;
            }
            get => Money;
        }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="wordNum"></param>
        public char this[int wordNum]
        {
            get => Name[wordNum];
        }

        
        private User(): this("默认名字")
        {
        }

        public void Deconstruct(out string name, out int age)
        {
            name = Name;
            age = Age;
        }

        public void InvokeDeconstruct()
        {
            (string name, int age) = this;
            Console.WriteLine($"name:{name}, age:{age}");
        }
        public User(string name): base()
        {
            Name = name;
        }

        public static User NewInstance()
        {
            return new User();
        }

        public int Age { get; set; } = 10;

        public int NextAge()
        {
            return Age + 1;
        }
        /// <summary>
        /// 强转的几种方式
        /// </summary>
        /// <returns></returns>
        public Person ToPerson()
        {
            // 不成功就返回null
            return this as Person;
            // return this;
        }

        public int NextAge(int year) => Age + year;

        public int? NextAge(ref int year)
        {
            year = 1;
            return this.Age + year;
        }

        public (string username, int age) GetInfo()
        {
            return (Name, Age);
        }
    }
}